using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using UnityEngine;

namespace SinceTimes.NetWork
{
    public partial class Net
    {
        [Header("捕捉REQUEST请求返回异常，会误捕捉UI上的异常")]
        /// <summary>
        /// 捕捉消息回调过程中的异常（Error）。
        /// 注：定位异常时可以关掉这个捕捉。
        /// </summary>
        public bool Catch_Response_ERR = true;
        [Header("每次处理推送消息数量")]
        public int OnceDealWithRevivedCount = 1;

        //发送池- 
        protected ConcurrentQueue<IPeerMessage> __SendPool = new ConcurrentQueue<IPeerMessage>();

        /// 发送池 有活动的Peer 自主拉取自行发送
        public IPeerMessage TopOneSending(int type)
        {
            IPeerMessage msg = null;

            if(__SendPool.Count > 0)
            {
                __SendPool.TryDequeue(out msg);
                if(msg!=null)
                {
                    MessageLastSend = msg;
                }
            }
            return msg;
        }



        //接受- 服务端主动发送的内容..
        protected ConcurrentQueue<IPeerMessage> __ReceivePool = new ConcurrentQueue<IPeerMessage>();

        public IPeerMessage TopOneRevived()
        {
            IPeerMessage _MSG = null;

            if (__ReceivePool.Count > 0)
            {
                __ReceivePool.TryDequeue(out _MSG);
                if (_MSG != null)  MessageLastReceive = _MSG;
            }

            return _MSG;
        }



        //接受- 客户端主动请求后 服务端的回复..
        protected ConcurrentQueue<IPeerMessage> __ResponsePool = new ConcurrentQueue<IPeerMessage>();
        public IPeerMessage TopOneResponsed()
        {
            IPeerMessage _MSG = null;

            if (__ResponsePool.Count > 0)
            {
                __ResponsePool.TryDequeue(out _MSG);
                if (_MSG != null)
                {

                    MessageLastReceive = _MSG;
                }
            }

            return _MSG;
        }



        // 客户端主动请求的时候 建立的 请求等待..
        protected Dictionary<int, Requester> __RequestePool = new Dictionary<int, Requester>();

        void Update()
        {
            //调用原来的FixedUpdate
            Polling();
            //处理 主动请求的回复.. 立马调度
            IPeerMessage _MSG;
            do
            {
                _MSG = TopOneResponsed();

                if (_MSG == null)
                    continue;


                if (Catch_Response_ERR)
                {
                    try
                    {
                        //通过 消息索引 检查是否是 
                        // if ( _MSG.Serial > 0 && _Requesters.ContainsKey(_MSG.Serial))
                        if (_MSG.MessageIndex > 0 && __RequestePool.ContainsKey(_MSG.MessageIndex))
                        {
                            // _DELAY = _Requesters[_MSG.Serial].Response(_MSG).Delay;
                            _DELAY = __RequestePool[_MSG.MessageIndex].Response(_MSG).Delay;
                        }
                    }
                    catch (Exception ex)
                    {
                        if (Net.SHOWERROR)
                            Debug.Log($"[Net.Responser]:Error of {ex.Message} @{_MSG}");
                    }
                }
                else
                {
                    //通过 消息索引 检查是否是 
                    if (_MSG.MessageIndex > 0 && __RequestePool.ContainsKey(_MSG.MessageIndex))
                        _DELAY = __RequestePool[_MSG.MessageIndex].Response(_MSG).Delay;
                }

            } while (_MSG != null);

            
        }

        int _ReconnectingCheckCount = 0;
        bool _IsPeerHealthy()
        {
            var _peers = GetComponentsInChildren<IPeer>();
            if (_peers == null)
            {
                return false;
            }
            else
            {
                foreach (var peer in _peers)
                {
                    
                    if(peer!=null && peer.State== PeerState.Connecting)
                    {
                        return true;
                    }
                    
                    //if (peer != null && !peer.Connected)
                    //{
                    //    if (BadPeerDestroyable)
                    //        GameObject.Destroy(peer.gameObject);

                    //    if (Net.SHOWERROR)
                    //        Debug.Log($"[NET._IsPeerHealthy] bad peer:{peer.gameObject}");
                    //}


                    if (peer.Connected)
                        return true;
                }

                return false;

            }
        }


        // Update is called once per frame
        float _LastReconnectingCheck = 0;
        void _CheckConnecting()
        {
            //健康检测
            if (Time.realtimeSinceStartup - _LastReconnectingCheck > PeerHealthyDuration)
            {
                if (__PoolItems_Out > 0)
                {
                    if (_IsPeerHealthy())
                        _ReconnectingCheckCount = 0;
                    else
                        _ReconnectingCheckCount++;

                    if (_ReconnectingCheckCount >= 5)
                    {


                        _CreatePeer(true);
                        _ReconnectingCheckCount = 0;
                    }
                }
                _LastReconnectingCheck = Time.realtimeSinceStartup;
            }
       }



        public   IPeerMessage MessageLastReceive, MessageLastSend;
        /// <summary>
        /// FixedUpdate 改成Polling因为TimeScale=0的时候FixedUpdate不触发
        /// </summary>
        void Polling()
        {
            __PoolItems_In = __ReceivePool.Count + __ResponsePool.Count;
            __PoolItems_Out =__SendPool.Count;

            //检查重连....
            if (AutoReconnect)
                _CheckConnecting();

            if (OnceDealWithRevivedCount <= 0)
                OnceDealWithRevivedCount = 1;

            for (int i = 0; i < OnceDealWithRevivedCount; i ++)
            {
                //处理接受--被动接受
                var _MSG = TopOneRevived();
                if (_MSG != null)
                {

                    if (Catch_Response_ERR)
                    {
                        try
                        {
                            _DoMessageHandle(_MSG);
                        }
                        catch (Exception ex)
                        {
                            if (Net.SHOWERROR)
                                Debug.Log($"[Peer._DoRecive]:Error ={ex.Message}\n{ex.StackTrace}");
                        }
                    }
                    else
                    {
                        _DoMessageHandle(_MSG);
                    }
                }
                else
                {
                    break;
                }
            }
        }

        protected virtual void _DoMessageHandle(IPeerMessage _msg)
        {
            foreach (var handle in _Handlers)
                handle.HandleOne(_msg);
        }
    }
}
